昨日介紹了Opentelemetry 的元件以及基本上的流程,但是沒有提到這些元件是如何做到Trace。
這邊我簡單說一下做到Trace的概念,這個概念就是Context propagation(上下文傳播)。
那我們可以Context propagation拆成兩個概念來看,首先是Context(上下文),我自己覺得可以用一句,曾經有人跟我說過的話來形容:「寫東西要有起、承、轉、合,要有上下文的概念」,假設你簡報上文在講可觀測性,你下一頁肯定是先說明這頁內容與上一頁可觀測性的關聯,因為為什麼,所以怎麼樣。不知道為什麼我在看到上下文傳播的時候,我總是會想起這句話。
如果你看不懂我的例子,那讓我們來看看官方的形容
例如,如果服務 A 呼叫服務 B,則服務 A 中 ID 位於上下文中的 Span 將用作服務 B 中建立的下一個 Span 的父 Span。中創建了Span,這意味著該Span 與服務A 中的Span 屬於同一追蹤的一部分。
其實就是讓上一個微服務紀錄的內容,可以接續往下繼續紀錄,形成一個完整的Trace。
這裡有提到Span我會在後面再詳細敘述,這裡暫時先不談。
談完了Context(上下文),接著來談談propagation(傳播),從上面我舉的例子來說propagation就像是上文要接續下文的那段敘述,舉例來說:「因為可觀測性,而目前流行的可觀測性解決方案是Opentelemetry,所以我接下來要介紹Opentelemetry。」
如果沒有這段敘述就會變成,「因為可觀測性,所以我接下來要介紹Opentelemetry。」看起來就是沒頭沒尾的一句話。
如果你看不懂我的例子,那讓我們來看看官方的形容
傳播是在服務和processes之間移動上下文的機制。它序列化或反序列化上下文對象,並提供要從一個服務傳播到另一個服務的相關資訊。
傳播通常由檢測庫處理,並且對使用者是透明的。如果您需要手動傳播上下文,可以使用Propagators API。
OpenTelemetry 維護幾個官方傳播器。預設傳播器使用 W3C TraceContext規範指定的標頭。
簡單來說,上述我們提到Context(上下文),是上一個微服務紀錄的內容,可以接續往下繼續紀錄,形成一個完整的Trace。那這件事情是誰做?就是propagation(傳播)。
簡單介紹完上下文傳播之後,我們回頭介紹一下,上述有提到但是沒有講的東西,就是「Span」以及傳播使用「W3C TraceContext的標頭」。
先來談談什麼是Span,Span就像是紀錄一個動作、一筆資料,Trace是由多個Span而組成的。
老樣子看完我的形容,不如我們看看官方文件是怎麼形容的吧
Span 代表一個工作或操作單元。 Span 是 Traces 的一個區塊。在 OpenTelemetry 中,它們包含以下資訊
既然Span是在紀錄東西,會長什麼樣子呢?
{
"name": "/v1/sys/health",
"context": {
"trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d",
"span_id": "086e83747d0e381e"
},
"parent_id": "",
"start_time": "2021-10-22 16:04:01.209458162 +0000 UTC",
"end_time": "2021-10-22 16:04:01.209514132 +0000 UTC",
"status_code": "STATUS_CODE_OK",
"status_message": "",
"attributes": {
"net.transport": "IP.TCP",
"net.peer.ip": "172.17.0.1",
"net.peer.port": "51820",
"net.host.ip": "10.177.2.152",
"net.host.port": "26040",
"http.method": "GET",
"http.target": "/v1/sys/health",
"http.server_name": "mortar-gateway",
"http.route": "/v1/sys/health",
"http.user_agent": "Consul Health Check",
"http.scheme": "http",
"http.host": "10.177.2.152:26040",
"http.flavor": "1.1"
},
"events": [
{
"name": "",
"message": "OK",
"timestamp": "2021-10-22 16:04:01.209512872 +0000 UTC"
}
]
}
那這個Span跟上下文有什麼關係呢?如果說Context propagation是一個機制、概念,那Trace、Span就是會使用到這個機制的角色。
再看一次文件怎麼說明上下文
例如,如果服務 A 呼叫服務 B,則服務 A 中 ID 位於上下文中的 Span 將用作服務 B 中建立的下一個 Span 的父 Span。中創建了Span,這意味著該Span 與服務A 中的Span 屬於同一追蹤的一部分。
A微服務上下文中的Span會作為B微服務Span的Parent Span再繼續往下,使整個Trace能夠完整。
所以我們可以看到,除了名稱、ID這種基本的訊息以外,其實比較特別的是Context、parent_id、attributes等,我們可以從Context得知trace_id、span_id,attributes包含有關Span的各種詳細資訊,走的協定、協定的版本、Server的host IP等
那既然這個上下文傳播概念會隨著Trace、Span存在,而這兩個角色又要擁有這麼多資訊,為此定義一個標頭,好像也合情合理,有spec定義什麼都好說。
上下文會分成traceparent、tracestate兩個部分
我們直接來看看文件中是怎麼定義的
traceparent 是分佈式追蹤中用來追蹤單個請求的標識,它提供了請求在整個追蹤圖中的位置。具體而言,這些資訊會告訴我們當前的請求屬於哪一個「追蹤」以及它在這個追蹤中的哪個「span」(單個操作單元)。這個標準字段的格式是固定長度的,設計上是為了方便解析並提升性能。
tracestate 是 traceparent 的擴展,用來攜帶廠商特定的資訊,這些資訊通常以「名稱/值對」的形式表示。這一部分是可選的,且不同的追蹤提供商可以使用這部分來存儲自定義資料。
我們來看看 traceparent HTTP Header 都有些什麼
version
trace-id
parent-id
trace-flags
基本上不外乎就是Trace、Span有的東西,畢竟這些標頭資訊就是為這些角色所定義的,最後我們來看看如果我們將上述這些概念圖像化會長成什麼樣子
那大家可以從上圖看到,有一條「client」是最長的其實就是這筆「Trace」,那是由底下數個「Span」所組成,例如:/api 、 /authN 、 /payment Gateway等
今日做個總結
OpenTelemetry Concepts
W3C Trace Context
Opentelemetry Span
讚讚, 小弟十一月的ithome鐵人講堂
題目剛好也是context propagation
內容連結
太感謝您了,過去就有在閱讀您的鐵人賽文章,從您的講堂中一定能讓我學習到更多。